/**
 * 
 */
package view.impl.ingame;

import org.newdawn.slick.Graphics;

import view.impl.PositionOffset;
import view.impl.ingame.animation.ActionAnimation;
import view.impl.ingame.animation.AnimationLoadException;
import view.impl.ingame.animation.AnimationLoader;
import view.impl.ingame.animation.AttackAction;
import view.impl.ingame.animation.EActionType;

/**
 * @author Julian Lindblad
 *
 */
public class Fighter implements IGameObject {
	
	private static final int PLAYER1_POSX = 330;
	private static final int PLAYER2_POSX = 470;
	
	public enum Player { PLAYER1, PLAYER2 };
	
	private Player player;
	
	private double depth;
	
	private ActionAnimation idle = null;
	private ActionAnimation strongAttack = null;
	private ActionAnimation fastAttack = null;
	private ActionAnimation preciseAttack = null;
	
	private ActionAnimation magicFire = null;
	
	private ActionAnimation winAnim = null;
	private ActionAnimation loseAnim = null;
	
	private ActionAnimation playing = null;
	private PositionOffset offset = PositionOffset.TOP_LEFT;
	
	private boolean playingAction = false;
	
	private boolean successfulAttack = false;
	
	private int posX;
	private int posY;
	private float horOff;
	private float verOff;
	
	public Fighter(Player player, double depth, int ground) {
		this.player = player;
		this.depth = depth;
		posX = player == Player.PLAYER1 ? PLAYER1_POSX : PLAYER2_POSX;
		posY = ground;
		
	}
	
	public Player getPlayer() {
		return player;	 
	}
	
	 
	public void loadCharacter(String characterFolder) throws AnimationLoadException {
		
		idle = AnimationLoader.loadAnimation(characterFolder, "idle", this);
		strongAttack = AnimationLoader.loadAnimation(characterFolder, "strong_attack", this);
		fastAttack = AnimationLoader.loadAnimation(characterFolder, "fast_attack", this);
		preciseAttack = AnimationLoader.loadAnimation(characterFolder, "precise_attack", this);
		
		magicFire = AnimationLoader.loadAnimation(characterFolder, "magic_fire", this);
		
		winAnim = AnimationLoader.loadAnimation(characterFolder, "win", this);
		loseAnim = AnimationLoader.loadAnimation(characterFolder, "lose", this);
		
		playing = idle;
		
		playing.start();
		
		offset = player == Player.PLAYER1 ? PositionOffset.BOTTOM_LEFT : PositionOffset.BOTTOM_RIGHT;
		horOff = (float) (0.5 * (offset.ordinal() % 3));
		verOff = (float) (0.5 * ((int)offset.ordinal() / 3));  // OBS! Detta �r korrekt!
	}
	
	public void setAnimation(String animation, boolean successfulAttack) {
		playing.stop();
		
		if(animation.toLowerCase().equals("strong_attack")) {
			playing = strongAttack;
			
		} else if(animation.toLowerCase().equals("fast_attack")) {
			playing = fastAttack;
			
		} else if(animation.toLowerCase().equals("precise_attack")) {
			playing = preciseAttack;
			
		} else if(animation.toLowerCase().equals("magic_fire")) {
			playing = magicFire;
			
		} else if(animation.toLowerCase().equals("battle_start")) {
			playing = idle;
			
		} else if(animation.toLowerCase().equals("win")) {
			playing = winAnim;
			
		} else if(animation.toLowerCase().equals("lose")) {
			playing = loseAnim;
			
		} else if(animation.toLowerCase().equals("draw")) {
			playing = loseAnim;
			
		}
		
		playingAction = true;
		this.successfulAttack = successfulAttack;
		playing.restart();
	}
	
	public boolean isPlayingAction() {
		return playingAction;
	}
	
	/* (non-Javadoc)
	 * @see client.view.IGameObject#draw()
	 */
	@Override
	public void draw(Graphics g, int windowWidth, int windowHeight) {
		
		checkAnimation();
		
		float scaleX = (float)windowWidth / 800f;
		float scaleY = (float)windowHeight / 600f;

		playing.draw(posX - horOff * playing.getWidth() * scaleX, 
				 	 posY - verOff * playing.getHeight() * scaleY, 
				 	 playing.getWidth() * scaleX, 
				 	 playing.getHeight() * scaleY);
	}
	
	public void addEffects(EffectDispatch ed, Graphics g, int windowWidth, int windowHeight) {
		if(playing.getActionType() == EActionType.ATTACK ) {
			AttackAction aa = (AttackAction)playing;
			
			float scaleX = (float)windowWidth / 800f;
			float scaleY = (float)windowHeight / 600f;

			aa.addEffects(posX - horOff * playing.getWidth() * scaleX, 
					 	  posY - verOff * playing.getHeight() * scaleY, 
					 	  ed,
					 	  successfulAttack);
		}
	}
	
	private void checkAnimation() {
		if(playing != idle && playing.isStopped() && 
		   playing != loseAnim && playing != winAnim) {
			playing = idle;
			playing.restart();
			playingAction = false;
		} else if(playing == idle) {
			playingAction = false;
		}
	}
	
	public void setPosX(int pos) {
		posX = pos;
	}
	
	public int getPosX() { 
		return posX; 
	}
	
	public int getPosY() { 
		return posY; 
	}

	/* (non-Javadoc)
	 * @see client.view.IGameObject#getDepth()
	 */
	@Override
	public double getDepth() {
		return depth;
	}

	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(IGameObject o) {
		return (int) Math.signum(this.depth - o.getDepth());
	}

}
